using UnityEngine;
using System.Collections;

/// \class  gkShootInRhythmPlayerCylindricalMovement
/// \brief 	the player cylindrical movement controller
[AddComponentMenu("GK/ShootInRhythm/Player/gkShootInRhythmPlayerCylindricalMovement")]
[RequireComponent(typeof(gkInputAccelerometer))]
[RequireComponent(typeof(gkCylindricalPosition))]
[RequireComponent(typeof(gkCylindricalInnerOrientationConstraint))]
[RequireComponent(typeof(gkCylindricalPhysicController))]
[RequireComponent(typeof(gkPhysicComponent))]
public class gkShootInRhythmPlayerCylindricalMovement : MonoBehaviour
{
	/// The maximum speed in degree by seconds
    public float MaxAngularSpeed = 180.0f;
	
	/// The sensibility dead zone in axis percent
    public float DeadZone = 0.1f;
	
	/// The accelerometer input
	private gkInputAccelerometer m_rInputAccelerometer;

    /// The physic component
    private gkPhysicComponent m_rPhysicComponent;
	
	/// The cylindrical position
    private gkCylindricalPosition m_rCylindricalPosition;
	
    /// \brief  Called just after the game begin to play
    void Start()
    {
        // Grab input
		m_rInputAccelerometer = GetComponent<gkInputAccelerometer>();

        // Grab the physic component
        m_rPhysicComponent = GetComponent<gkPhysicComponent>();
		
		// Grab the cylindrical position component
		m_rCylindricalPosition = GetComponent<gkCylindricalPosition>();
	}
	
	/// \brief  Called each frame
    void Update()
    {
		Vector3 f3CurrentCylindricalPosition;
		Vector3 f3TargetCylindricalPosition;
		Vector3 f3WantedMovement;
		Vector3 f3velocity;
		Vector3 f3TiltPercent;
		
		// Get the accelerometer tilt percent
		f3TiltPercent = m_rInputAccelerometer.GetTiltPercent();
		
		if(f3TiltPercent.sqrMagnitude > (DeadZone * DeadZone))
		{
			// Get the current cylindrical position
			f3CurrentCylindricalPosition = m_rCylindricalPosition.position;
			
			// Compute the new cylindrical position 
			f3TargetCylindricalPosition = f3CurrentCylindricalPosition;
			f3TargetCylindricalPosition.y = Mathf.Rad2Deg * Mathf.Atan2(f3TiltPercent.y, f3TiltPercent.x);
			
			// Compute the wanted movement
			f3WantedMovement = f3TargetCylindricalPosition - f3CurrentCylindricalPosition;
			
			// Get the more direct angle
			if(f3WantedMovement.y >= 180.0f)
			{
				f3WantedMovement.y -= 360.0f;	
			}
			else if(f3WantedMovement.y <= -180.0f)
			{
				f3WantedMovement.y += 360.0f;
			}
			
			//Compute the velocity to execute the wanted movement
			f3velocity = f3WantedMovement/Time.deltaTime;
			
			// Clamp it with the max angular speed
			f3velocity.y = Mathf.Clamp(f3velocity.y, -MaxAngularSpeed, MaxAngularSpeed);
			
		    // Apply the velocity
	        m_rPhysicComponent.SetLinearVelocity(f3velocity);
		}
		else
		{
			// Apply the velocity
	        m_rPhysicComponent.SetLinearVelocity(Vector3.zero);
		}
    }
}